home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Games
/
Chess
/
Source
/
gnuglue.m
< prev
next >
Wrap
Text File
|
1994-04-01
|
13KB
|
582 lines
#include <stdio.h>
#include <ctype.h>
#include <sys/param.h>
#include <sys/times.h>
#include <sys/file.h>
#include <pwd.h>
#import <appkit/appkit.h>
#import "chess_strings.h"
#import "Chess.h"
#import "gnuchess.h"
#import "gnuglue.h"
#import "Clock.h"
#import "gnuchess.h"
#import "Board.h"
#import "ResponseMeter.h"
#define LEFT_CASTLE 0x1
#define RIGHT_CASTLE 0x2
extern short GameQueens[240];
extern short PieceList[2][16];
extern short PieceCnt[2];
extern algbr();
extern castle();
/* extern getsectdata(); */
extern distance();
extern InitializeStats();
extern SqAtakd();
struct tms tmbuf1,tmbuf2;
OutputMove()
{
int i, r1, c1, r2, c2, castle_flag;
#ifdef NeXT_DEBUG
printf( "OutputMove: " );
printf( "Computer move is %s, ", mvstr1 );
printf( "mask 0x%04x\n", root->flags );
#endif
if( root->flags & draw )
[NXApp setFinished: DRAW_GAME];
if( [[NXApp clockWindow] isVisible] ){
if( player == white )
[[NXApp whiteMeter] displayFilled];
else
[[NXApp blackMeter] displayFilled];
}
if( !*mvstr1 ){
#ifdef NeXT_DEBUG
printf( "NO COMPUTER MOVE\n" );
#endif
return;
}
convert_algbr( mvstr1, &r1, &c1, &r2, &c2, &castle_flag );
[[NXApp gameBoard] highlightSquareAt: r1 : c1];
[[NXApp gameBoard] slidePieceFrom: r1 : c1 to: r2 : c2];
[NXApp storePosition: r2 : c2];
[[NXApp gameBoard] layoutBoard: board color: color];
[[NXApp gameBoard] display];
NXPing();
[[NXApp gameBoard] highlightSquareAt: r2 : c2];
#ifdef NeXT_DEBUG
printf( "White has %d pieces\n", PieceCnt[0] );
for( i = 0; i <= PieceCnt[0]; i++ )
printf( "%02d ", board[PieceList[0][i]] );
printf( "\n" );
printf( "Black has %d pieces\n", PieceCnt[1] );
for( i = 0; i <= PieceCnt[1]; i++ )
printf( "%02d ", board[PieceList[1][i]] );
printf( "\n" );
#endif
}
SetTimeControl()
{
#ifdef NeXT_DEBUG
printf( "SetTimeControl\n" );
#endif
if (TCflag)
{
TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes;
}
else
{
TimeControl.moves[white] = TimeControl.moves[black] = 0;
TimeControl.clock[white] = TimeControl.clock[black] = 0;
Level = 60*(long)TCminutes;
}
et = 0;
ElapsedTime(1);
}
SelectLevel()
{
}
ElapsedTime( short iop )
/*
Determine the time that has passed since the search was started. If
the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
timeout to true which will terminate the search.
*/
{
NXEvent peek_ev, *get_ev;
et = time((long *)0) - time0;
if (et < 0)
et = 0;
ETnodes += 50;
if( !iop ){
if( [[NXApp clockWindow] isVisible] ){
if( player == white )
[[NXApp whiteMeter] display];
else
[[NXApp blackMeter] display];
NXPing();
}
}
#ifdef TIME_STUFF
printf( "ResponseTime %d, ExtraTime %d, Sdepth %d, iop %d, et %d, et0 %d\n",
ResponseTime, ExtraTime, Sdepth, iop, et, et0 );
#endif
if (et > et0 || iop == 1){
if (et > ResponseTime+ExtraTime && Sdepth > 1){
timeout = true;
}
et0 = et;
if (iop == 1){
time0 = time((long *)0);
et0 = 0;
}
#ifdef PROFILE
(void) times(&tmbuf2);
cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
if (cputimer > 0)
evrate = (100*NodeCnt)/(cputimer+100*ft);
else
evrate = 0;
#endif
ETnodes = NodeCnt + 50;
UpdateClocks();
}
if( [NXApp peekNextEvent: NX_MOUSEDOWNMASK into: &peek_ev] ){
get_ev = [NXApp getNextEvent: NX_MOUSEDOWNMASK];
[NXApp sendEvent: get_ev];
#ifdef NeXT_DEBUG
printf( "mousedown event, sending to application\n" );
#endif
}
}
UpdateClocks()
{
}
ShowResults( short score, unsigned short bstline[], char ch )
{
#ifdef NeXT_DEBUG
printf( "ShowResults: " );
printf("score = %d",score);
printf(" %5s\n", mvstr1 );
#endif
}
GameEnd( short score )
{
NXBeep();
if( root->flags & draw ){
[NXApp setFinished: DRAW_GAME];
}
else if( score == 9998 ){
printf( "score %d, winner %d\n", score, winner );
[NXApp setFinished: winner == black ? BLACK_MATE : WHITE_MATE];
}
else if( score == -9999 ){
if( bothsides ){
printf( "score %d, winner %d\n", score, winner );
if( winner != -1 )
[NXApp setFinished: winner == white ? WHITE_MATE : BLACK_MATE];
else
[NXApp setFinished: WHITE_MATE];
}
else
[NXApp setFinished: OPPONENT_MATE ];
}
}
ClrScreen()
{
}
UpdateDisplay( short f, short t, short flag, short iscastle )
{
#ifdef NeXT_DEBUG
printf( "Update Display: from %d, to %d, flag 0x%04x, iscastle %d, InChk %d\n",
f, t, flag, iscastle, InChk );
#endif
[[NXApp gameBoard] layoutBoard: board color: color];
[[NXApp gameBoard] display];
}
InCheck()
{
int incheck = -1;
if( SqAtakd( PieceList[computer][0], opponent ) )
incheck = computer;
if( SqAtakd( PieceList[opponent][0], computer ) )
incheck = opponent;
if( incheck == black )
ShowMessage( "Black is in check" );
else if( incheck == 0 )
ShowMessage( "White is in check" );
}
GetOpenings()
/*
Read in the Opening Book file and parse the algebraic notation for a
move into an unsigned integer format indicating the from and to
square. Create a linked list of opening lines of play, with
entry->next pointing to the next line and entry->move pointing to a
chunk of memory containing the moves. More Opening lines of up to 256
half moves may be added to gnuchess.book.
*/
{
int c,i,j,side;
struct BookEntry *entry;
unsigned short mv,*mp,tmp[100];
int book_size;
char *book_data;
NXStream *book_stream;
book_data = (char *)getsectdata( "__BOOK", "gnuchess.book", &book_size);
if( book_data != NULL ){
book_stream = NXOpenMemory( book_data, book_size, NX_READONLY );
Book = NULL;
i = 0; side = white;
while((c = parse( book_stream, &mv, side)) >= 0 ){
if(c == 1){
tmp[++i] = mv;
side = otherside[side];
}
else if (c == 0 && i > 0){
entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
entry->mv = mp;
entry->next = Book;
Book = entry;
for (j = 1; j <= i; j++) *(mp++) = tmp[j];
*mp = 0;
i = 0; side = white;
}
}
NXCloseMemory( book_stream, NX_SAVEBUFFER );
}
}
int
parse( NXStream *book_stream, unsigned short *mv, short side )
{
int c,i,r1,r2,c1,c2;
char s[100];
while ((c = NXGetc( book_stream )) == ' ');
i = 0; s[0] = c;
while (c != ' ' && c != '\n' && c != EOF)
s[++i] = c = NXGetc( book_stream );
s[++i] = '\0';
if (c == EOF)
return(-1);
if (s[0] == '!' || i < 3){
while (c != '\n' && c != EOF) c = NXGetc( book_stream );
return(0);
}
if (s[4] == 'o'){
if (side == black)
*mv = 0x3C3A;
else
*mv = 0x0402;
}
else if (s[0] == 'o'){
if (side == black)
*mv = 0x3C3E;
else *mv = 0x0406;
}
else{
c1 = s[0] - 'a'; r1 = s[1] - '1';
c2 = s[2] - 'a'; r2 = s[3] - '1';
*mv = (locn[r1][c1]<<8) + locn[r2][c2];
}
return(1);
}
ShowDepth( char ch )
{
#ifdef NeXT_DEBUG_X
printf( "ShowDepth: %d%c max %d\n", Sdepth, ch, MaxSearchDepth );
#endif
}
ShowCurrentMove( short pnt, short f, short t )
{
#ifdef NeXT_DEBUG
printf( "ShowCurrentMove\n" );
algbr(f,t,false);
printf("(%2d) %4s",pnt,mvstr1);
#endif
}
ShowSidetomove()
{
#ifdef NeXT_DEBUG
printf( "ShowSidetomove\n" );
if (player == white)
printf("%2d: WHITE\n",1+(GameCnt+1)/2);
else
printf("%2d: BLACK\n",1+(GameCnt+1)/2);
#endif
}
ShowMessage( char *s )
{
#ifdef NeXT_DEBUG
printf( "ShowMessage: %s\n", s );
#endif
[NXApp setTitleMessage: s];
}
void
ExitChess()
{
[NXApp terminate: NXApp];
exit(0);
}
extern char playing;
void
Die()
{
if( NXRunAlertPanel( 0, "Do you want to exit chess?", "Yes", "No", 0 ) ){
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
ExitChess();
}
}
void
TerminateSearch()
{
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
timeout = true;
if( bothsides )
playing = 0;
signal( SIGINT, Die );
signal( SIGQUIT, Die );
}
SearchStartStuff( short side )
{
signal(SIGINT,TerminateSearch);
signal(SIGQUIT,TerminateSearch);
}
static char convert_buf[8];
char *
convert_rc( int row, int col, int row2, int col2, int type )
{
if( type == king && col == 4){
if( col2 == 6 ){
strcpy( convert_buf, "o-o" );
return( convert_buf );
}
else if( col2 == 2 ){
strcpy( convert_buf, "o-o-o" );
return( convert_buf );
}
}
convert_buf[0] = 'a' + col;
convert_buf[1] = '0' + row+1;
convert_buf[2] = 'a' + col2;
convert_buf[3] = '0' + row2+1;
convert_buf[4] = 0;
return( convert_buf );
}
convert_algbr(char *algbr, int *r1, int *c1, int *r2, int *c2,int *castle_flag)
{
int type;
*castle_flag = 0;
if( strcmp( algbr, "o-o" ) == 0 )
*castle_flag = RIGHT_CASTLE;
else if( strcmp( algbr, "o-o-o" ) == 0 )
*castle_flag = LEFT_CASTLE;
else{
*c1 = algbr[0] - 'a';
*r1 = algbr[1] - '0' - 1;
*c2 = algbr[2] - 'a';
*r2 = algbr[3] - '0' - 1;
}
type = [[NXApp gameBoard] typeAt: *r1 : *c1];
if( type ){
#ifdef NeXT_DEBUG
printf( "type: %d\n", type );
#endif
if( type == king ){
if( *c1 == 4 && *c2 == 6 )
*castle_flag = RIGHT_CASTLE;
else if( *c1 == 4 && *c2 == 2 )
*castle_flag = LEFT_CASTLE;
}
}
return;
}
GetGame( const char *fname )
{
FILE *fd;
int r, c;
short sq;
unsigned short m;
if ((fd = fopen(fname,"r")) != NULL){
fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
fscanf(fd,"%hd%hd%hd%hd",
&castld[white],&castld[black],
&kingmoved[white],&kingmoved[black]);
fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
fscanf(fd,"%ld%ld%hd%hd",
&TimeControl.clock[white],&TimeControl.clock[black],
&TimeControl.moves[white],&TimeControl.moves[black]);
for (sq = 0; sq < 64; sq++){
fscanf(fd,"%hd",&m);
board[sq] = (m >> 8);
color[sq] = (m & 0xFF);
if(color[sq] == 0)
color[sq] = neutral;
else
--color[sq];
}
[[NXApp gameBoard] layoutBoard: board color: color];
[[NXApp gameBoard] display];
GameCnt = -1; c = '?';
while (c != EOF)
{
++GameCnt;
c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
&GameList[GameCnt].score,&GameList[GameCnt].depth,
&GameList[GameCnt].nodes,&GameList[GameCnt].time,
&GameList[GameCnt].piece,&GameList[GameCnt].color);
if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
else --GameList[GameCnt].color;
}
GameCnt--;
if (TimeControl.clock[white] > 0) TCflag = true;
computer--; opponent--;
}
fclose(fd);
InitializeStats();
UpdateDisplay(0,0,1,0);
Sdepth = 0;
}
SaveGame( const char *fname )
{
FILE *fd;
short sq,i,c;
fd = fopen(fname,"w");
if( !fd )
return( 0 );
fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
fprintf(fd,"%d %d %d %d\n",
castld[white],castld[black],kingmoved[white],kingmoved[black]);
fprintf(fd,"%d %d\n",TCflag,OperatorTime);
fprintf(fd,"%ld %ld %d %d\n",
TimeControl.clock[white],TimeControl.clock[black],
TimeControl.moves[white],TimeControl.moves[black]);
for (sq = 0; sq < 64; sq++)
{
if (color[sq] == neutral) c = 0; else c = color[sq]+1;
fprintf(fd,"%d\n",256*board[sq] + c);
}
for (i = 0; i <= GameCnt; i++)
{
if (GameList[i].color == neutral) c = 0;
else c = GameList[i].color + 1;
fprintf(fd,"%d %d %d %ld %d %d %d\n",
GameList[i].gmove,GameList[i].score,GameList[i].depth,
GameList[i].nodes,GameList[i].time,
GameList[i].piece,c);
}
fclose(fd);
return( 1 );
}
ListGame( const char *filename )
{
FILE *fd;
short i,f,t;
fd = fopen(filename,"w");
if( !fd )
return( 0 );
fprintf(fd,"\n");
fprintf(fd," score depth nodes time ");
fprintf(fd," score depth nodes time\n");
for (i = 0; i <= GameCnt; i++){
f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
algbr(f,t,false);
if ((i % 2) == 0)
fprintf(fd,"\n");
else
fprintf(fd," ");
fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1,
GameList[i].score,GameList[i].depth,
GameList[i].nodes,GameList[i].time);
}
fprintf(fd,"\n\n");
fclose(fd);
return( 1 );
}
Undo()
/*
Undo the most recent half-move.
*/
{
short f,t;
f = GameList[GameCnt].gmove>>8;
t = GameList[GameCnt].gmove & 0xFF;
if (board[t] == king && distance(t,f) > 1) {
castle(GameList[GameCnt].color,f,t,2);
} else {
board[f] = board[t];
color[f] = color[t];
board[t] = GameList[GameCnt].piece;
color[t] = GameList[GameCnt].color;
if ( GameQueens[GameCnt] ) {
board[f] = GameQueens[GameCnt];
}
if (board[f] == king) --kingmoved[color[f]];
}
if (TCflag) ++TimeControl.moves[color[f]];
GameCnt--; mate = false; Sdepth = 0;
if ( [NXApp finished] ) {
[NXApp setFinished: false];
}
UpdateDisplay(0,0,1,0);
InitializeStats();
}